<template>
  <div class="chart-container">
    <div ref="chartRef" class="chart" :style="{ width: width, height: height }"></div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'
import * as echarts from 'echarts'

const props = defineProps({
  option: {
    type: Object,
    required: true
  },
  width: {
    type: String,
    default: '100%'
  },
  height: {
    type: String,
    default: '400px'
  },
  theme: {
    type: String,
    default: 'default'
  },
  autoResize: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits(['click', 'dblclick', 'mousedown', 'mouseover', 'mouseout'])

const chartRef = ref(null)
let chartInstance = null
let resizeObserver = null

// 初始化图表
const initChart = async () => {
  if (!chartRef.value) return
  
  try {
    // 确保DOM元素已准备就绪并有有效尺寸
    await nextTick()
    // 添加延迟以确保DOM已完全渲染
    await new Promise(resolve => setTimeout(resolve, 100))
    
    // 检查DOM元素是否有效
    if (!chartRef.value || !chartRef.value.offsetHeight || !chartRef.value.offsetWidth) {
      console.warn('Chart container has zero size, delaying initialization')
      // 如果容器尺寸为0，延迟再试
      setTimeout(initChart, 300)
      return
    }
    
    // 销毁现有实例（如果存在）
    if (chartInstance) {
      chartInstance.dispose()
    }
    
    chartInstance = echarts.init(chartRef.value, props.theme)
    
    // 设置配置项
    if (props.option) {
      chartInstance.setOption(props.option)
    }
    
    // 绑定事件
    chartInstance.on('click', (params) => emit('click', params))
    chartInstance.on('dblclick', (params) => emit('dblclick', params))
    chartInstance.on('mousedown', (params) => emit('mousedown', params))
    chartInstance.on('mouseover', (params) => emit('mouseover', params))
    chartInstance.on('mouseout', (params) => emit('mouseout', params))
  } catch (error) {
    console.error('Failed to initialize chart:', error)
  }
  
  // 自动调整大小
  if (props.autoResize) {
    window.addEventListener('resize', handleResize)
    
    // 使用 ResizeObserver 监听容器大小变化
    if (window.ResizeObserver) {
      resizeObserver = new ResizeObserver(() => {
        handleResize()
      })
      resizeObserver.observe(chartRef.value)
    }
  }
}

// 处理窗口大小变化
const handleResize = () => {
  if (chartInstance) {
    chartInstance.resize()
  }
}

// 更新图表配置
const updateChart = () => {
  try {
    if (chartInstance && props.option) {
      chartInstance.setOption(props.option, true)
    } else if (!chartInstance && chartRef.value) {
      // 如果图表实例不存在但DOM已就绪，重新初始化
      initChart()
    }
  } catch (error) {
    console.error('Failed to update chart:', error)
  }
}

// 清空图表
const clearChart = () => {
  try {
    if (chartInstance) {
      chartInstance.clear()
    }
  } catch (error) {
    console.error('Failed to clear chart:', error)
  }
}

// 销毁图表
const disposeChart = () => {
  try {
    if (chartInstance) {
      chartInstance.dispose()
      chartInstance = null
    }
  } catch (error) {
    console.error('Failed to dispose chart:', error)
  }
  
  try {
    if (resizeObserver) {
      resizeObserver.disconnect()
      resizeObserver = null
    }
    
    window.removeEventListener('resize', handleResize)
  } catch (error) {
    console.error('Failed to clean up event listeners:', error)
  }
}

// 获取图表实例
const getChartInstance = () => {
  return chartInstance
}

// 显示加载动画
const showLoading = (opts = {}) => {
  if (chartInstance) {
    chartInstance.showLoading({
      text: '加载中...',
      color: '#409EFF',
      textColor: '#409EFF',
      maskColor: 'rgba(255, 255, 255, 0.8)',
      zlevel: 0,
      ...opts
    })
  }
}

// 隐藏加载动画
const hideLoading = () => {
  if (chartInstance) {
    chartInstance.hideLoading()
  }
}

// 监听配置变化
watch(() => props.option, updateChart, { deep: true })

// 监听主题变化
watch(() => props.theme, () => {
  disposeChart()
  initChart()
})

// 暴露方法给父组件使用
defineExpose({
  getChartInstance,
  updateChart,
  clearChart,
  showLoading,
  hideLoading
})

onMounted(() => {
  initChart()
})

onUnmounted(() => {
  disposeChart()
})
</script>

<style scoped>
.chart-container {
  width: 100%;
  height: 100%;
}

.chart {
  width: 100%;
  height: 100%;
}
</style>
